package com.dycong.common.common.thread.pool;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 该线程工厂主要是给线程取一个名字
 * 使用方式：
 *  1：(推荐)配合Java线程池使用，
 *  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("my-threadname"));
 *  fixedThreadPool.execute(() -> {
 *      // do something
 *      System.out.println(Thread.currentThread().getName());
 *   });
 *
 *  2：直接使用
 *  new NamedThreadFactory().newThread(() -> System.out.println(Thread.currentThread().getName())).start();
 *
 * @author chenenzhi
 */
public class NamedThreadFactory implements ThreadFactory {

    private static final AtomicInteger POOL_SEQ = new AtomicInteger(1);

    private final AtomicInteger mThreadNum = new AtomicInteger(1);

    private final String mPrefix;

    private final boolean mDaemon;

    private final ThreadGroup mGroup;

    public NamedThreadFactory() {
        this("namedpool-" + POOL_SEQ.getAndIncrement(), false);
    }

    public NamedThreadFactory(String prefix) {
        this(prefix, false);
    }

    public NamedThreadFactory(String prefix, boolean daemon) {
        mPrefix = prefix + "-thread-";
        mDaemon = daemon;
        SecurityManager s = System.getSecurityManager();
        mGroup = (s == null) ? Thread.currentThread().getThreadGroup() : s.getThreadGroup();
    }

    @Override
    public Thread newThread(Runnable runnable) {
        String name = mPrefix + mThreadNum.getAndIncrement();
        Thread ret = new Thread(mGroup, runnable, name, 0);
        ret.setDaemon(mDaemon);
        // TODO: 2019/6/13 自定义的java.lang.Thread.UncaughtExceptionHandler接口实现即可 
        ret.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("UncaughtExceptionHandler catch" );
                e.printStackTrace();
            }
        });
        return ret;
    }

    public ThreadGroup getThreadGroup() {
        return mGroup;
    }
}
